/*
 * Tabladirecciones.cpp
 *
 *  Created on: 13/10/2009
 *      Author: hernan
 */

#include "Tabladirecciones.h"

Tabladirecciones::Tabladirecciones(){


}

Tabladirecciones::Tabladirecciones(const string& nombrearch)
{


	const string sufijotabla=".TABLADIRECCIONES";

	nombrearchivo=nombrearch + sufijotabla;

	arch= new ArchivoTexto(nombrearchivo);

	DeserealizarTabla();


}

Tabladirecciones::~Tabladirecciones() {


	SerializarTabla();
	delete arch;

}

void Tabladirecciones::DeserealizarTabla()
{
	string cadena;
	string cadenaaux;
	char c='0';
	int i;
	int Archcreado=0;

	arch->leerLinea(cadena);

	int j=0;

	while ((cadena.capacity()!=0)&& (cadena.empty()==0))

	{
	i =0;

	c='0';
	Archcreado=1;

	while (c!='.')
	{

		c=cadena.at(i);

		if ((c!='.')&&(c!='/')&&(c!='%'))
		{
			cadenaaux.push_back(c);
		}

		if (c=='/')
		{
			TamanioTabla=  atoi(cadenaaux.c_str());

			cadenaaux.clear();

			direcciones.reserve(TamanioTabla);

		}

		if (c=='%')
		{

			direcciones[j]=atoi(cadenaaux.c_str());

			j++;
			cadenaaux.clear();
		}

		i++;


	};

	arch->leerLinea(cadena);


	};

	if ((cadena.capacity()==0) || ( Archcreado=0 ))
		{

			TamanioTabla=1;

			if (direcciones.empty())
			{
				direcciones.reserve(TamanioTabla);
			}

			direcciones[0]=0; //Asigna a la posicion 0 de la tabla, el numero de cubo 0

			SerializarTabla();

			return;
		}

}

void Tabladirecciones::SerializarTabla()
{

	string cadena;
	const char separador1= '/';
	const char separador2= '%';
	unsigned int i=0;
	int longitud;
	int FIN=0;

	arch->clean();
	arch->irAlPrincipio();

	std::string s;
	std::stringstream out1;

	out1 << TamanioTabla;

	s=out1.str();

	cadena=cadena+s;

	s.clear();

	cadena.push_back(separador1);

	while (FIN==0)
	{

		longitud=0;

	for(;((i<TamanioTabla)&&( longitud < 30 ));i++)
	{

		std::string s;
		std::stringstream out;

		out << direcciones[i];

		s=out.str();

		cadena=cadena+s;

		s.clear();

		cadena.push_back(separador2);

		longitud++;

	}

	if ((i==TamanioTabla) && (longitud ==0))
	{

		FIN=1;

		return;
	}

	cadena.push_back('.');

	arch->escribir(cadena);

	cadena.clear();

	arch->terminarLinea();

	}

}

int Tabladirecciones::CrearTabla(const string& nombrearchivo)
{

	DeserealizarTabla();

	return 1;
}

int Tabladirecciones::DevolverNroCubo(unsigned int posiciontabla)
{
	if (posiciontabla>TamanioTabla) return -1;

	return direcciones[posiciontabla];


}


void Tabladirecciones::ModificarPosicion(int nuevonrocubo,int posicion)
{

	direcciones[posicion]=nuevonrocubo;

}

void Tabladirecciones::DuplicarTabla()
{
	unsigned int i;

	vector <int> vectoraux;

	for (i=0;i<TamanioTabla;i++)
	{
		vectoraux.push_back(direcciones[i]);

	}
	while (!direcciones.empty())
	{
	direcciones.pop_back();
	}



	for (i=0;i<TamanioTabla;i++)
	{
	direcciones.push_back(vectoraux[i]);
	}

	for (i=0;i<TamanioTabla;i++)
	{
	direcciones.push_back(vectoraux[i]);
	}

	TamanioTabla=TamanioTabla*2;
}


int Tabladirecciones::GetTamanio()
{
	return TamanioTabla;
}

int Tabladirecciones::VerificarSimetria()
{

	int salto,i;
	int simetria=0;

	salto=TamanioTabla/2;

	for (i=0;((i<=salto)&& (simetria = 0));i++)
	{
		if (direcciones[i]!=direcciones[i+salto])
		{
			simetria = 1;
		}

	}

	if (simetria==1)
	{
		return 1; // La tabla no es simetrica
	}

	return 0;
}


int Tabladirecciones::AcortarTabla()
{

	if (TamanioTabla<2)
	{
		return -1;
	}

	TamanioTabla=TamanioTabla/2;
	cout << "TAMANIO DE TABLA NUEVO " << TamanioTabla << endl;

	cout << "TAMANIO DIRECCIONES" << this->direcciones.size() << endl;
	cout << "kmsdflk " << this->direcciones[3]<< endl;

	while (this->direcciones.size()>TamanioTabla)
	{
		direcciones.pop_back();

	}

	return 0;
}

// Se mueve tamaniodisp/2 posiciones hacia arriba y abajo, en forma circular
// SI ambas posiciones de la tabla apuntan al mismo bloque, entonces puede eliminarse el bloque

int Tabladirecciones::AnalizarBaja(int posicionInicial, int tamanioDisp)
{
	int cantMov;
	int posicionMenor;
	int posicionMayor;
	int Tamanio;

	cantMov=tamanioDisp/2;

	posicionMenor=posicionInicial-cantMov;

	if ((posicionMenor)<0)
	{
		posicionMenor=TamanioTabla+posicionMenor;

	}

	posicionMayor=posicionInicial+cantMov;

	Tamanio=TamanioTabla;

	if ((posicionMayor)>=Tamanio)
	{
		posicionMayor= posicionMayor-TamanioTabla;

	}

	if (direcciones[posicionMayor]==direcciones[posicionMenor])
	{
		return direcciones[posicionMayor]; // El bloque puede eliminarse
	}

	return -1;
}
